﻿ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SmartPatientCentre.Models;
using SmartPatientCentre.Common;

namespace SmartPatientCentre.ViewModels
{
    public class ResultsViewModel
    {
        public List<UniqueResult> All { get; private set; }
        public List<UniqueResult> Sodium { get; private set; }
        public List<UniqueResult> Potassium { get; private set; }
        public List<UniqueResult> Urea { get; private set; }
        public List<UniqueResult> Creatinine { get; private set; }
        public List<UniqueResult> Dashboard { get; private set; }
        public Patient Patient { get; private set; }

        // Create class and Populate List<UniqueResult> from List<Result>
        public ResultsViewModel(Patient patient)
        {
            All = new List<UniqueResult>();
            Sodium = new List<UniqueResult>();
            Potassium = new List<UniqueResult>();
            Urea = new List<UniqueResult>();
            Creatinine = new List<UniqueResult>();
            Dashboard = new List<UniqueResult>();

            Patient = patient;
            var resultList = patient.Results as List<Result>;

            foreach (Result result in resultList)
            {
                this.CreateUniqueResult(result);
            }

            // Order Results by Date Descending
            this.OrderByDate();

            // Populate Difference property
            this.CalculateDifference(Sodium);
            this.CalculateDifference(Potassium);
            this.CalculateDifference(Urea);
            this.CalculateDifference(Creatinine);

            // Create Dashboard collection from each result type
            Dashboard.Add(Sodium.First());
            Dashboard.Add(Potassium.First());
            Dashboard.Add(Urea.First());
            Dashboard.Add(Creatinine.First());
        }

        // Create UniqueResult instances from Result
        // Also add to List<UniqueResult>
        private void CreateUniqueResult(Result result)
        {
            UniqueResult sodiumResult = new SodiumResult(result);
            All.Add(sodiumResult);
            Sodium.Add(sodiumResult);

            UniqueResult potassiumResult = new PotassiumResult(result);
            All.Add(potassiumResult);
            Potassium.Add(potassiumResult);

            UniqueResult ureaResult = new UreaResult(result);
            All.Add(ureaResult);
            Urea.Add(ureaResult);

            UniqueResult creatinineResult = new CreatinineResult(result, Patient);
            All.Add(creatinineResult);
            Creatinine.Add(creatinineResult);
        }

        // Order Result lists by Date
        private void OrderByDate()
        {
            All = All.OrderByDescending(r => r.Date).ToList();
            Sodium = Sodium.OrderByDescending(r => r.Date).ToList();
            Potassium = Potassium.OrderByDescending(r => r.Date).ToList();
            Urea = Urea.OrderByDescending(r => r.Date).ToList();
            Creatinine = Creatinine.OrderByDescending(r => r.Date).ToList();
        }

        // Method to calculate result difference from previous
        private void CalculateDifference(List<UniqueResult> list)
        {
            int listCount = list.Count;

            foreach (var result in list)
            {
                int previousResult = list.IndexOf(result) + 1;

                if (previousResult < listCount) // Check if the result is not last in the list
                {
                    result.Difference = result.Value - list[previousResult].Value;
                }
                else // No previous result to compare
                {
                    result.Difference = 0;
                }
            }
        }

        public List<UniqueResult> Select(string resultType)
        {
            switch (resultType)
            {
                case "Sodium":
                    return Sodium;

                case "Potassium":
                    return Potassium;

                case "Urea":
                    return Urea;

                case "Creatinine":
                    return Creatinine;

                default:
                    throw new Exception("Result type not found!");
            }
        }
    }
}
